#if !defined(_SENUM_H)
#define _SENUM_H

#include "SComplexValue.h"
#include "SNumber.h"
#include "SEnumTypeDescriptor.h"
#include "SException.h"
#include <boost/regex.hpp>

CREATE_ALIAS( SEnum );

/**
 * Class used to store an enumerator variable.
 */
class DECLARATION_DLL SEnum : public SComplexValue
{
	/** The key (or value) of the enumerator. */
	string value;

	/** The type descriptor of this variable. */
	SEnumTypeDescriptorSp typeDescriptor;

	/**
	 * Create an enum type variable with a specific value.
	 */
	SEnum(SEnumTypeDescriptorSp typeDescriptor, string value);

	public:

		/**
		 * Get the variable type.
		 */
		virtual SType GetType() const
		{
			return STypeEnum;
		}

		/**
		 *   Get the type descriptor.
		 */
		virtual TypeDescriptorSp GetTypeDescriptor()
		{
			return typeDescriptor;
		}

		/**
		 *   Set the enum value (with a string).
		 *   If the value is not defined a SArgumentException is raised.
		 */
		virtual void Set(string value);

		/**
 		 *   Set the enum value (with a number).
 		 *   If the value is not defined a SArgumentException is raised.
		 */
		virtual void Set(unsigned long value);

		/**
		 *   Get the enum key value.
		 */
		virtual string Get()
		{
			return value;
		}

		/**
		 *   Get the enum long value.
		 */
		virtual unsigned long GetNumericValue()
		{
			return typeDescriptor->GetNumericValue(value);
		}

		/**
		 * Returns a string representation of the value.
		 */
		virtual string ToString() 
		{ 
			return SComplexValue::ToString(); 
		}

		/**
		 * Returns a string representation of the value in a specific format.
		 */
		virtual string ToString(string format)
		{
			// Show the value
			if ( format != "")
			{
				SNumberSp n = SNumber::Create( GetNumericValue() );
				return n->ToString(format);
			}

			return value;
		}

		/**
		 *   Factory method to create a SEnum variable instance.
		 */
		static SEnumSp Create(SEnumTypeDescriptorSp typeDescriptor, string value);

		/**
		*   Factory method to create a SEnum variable instance from the underline value.
		*/
		static SEnumSp Create(SEnumTypeDescriptorSp typeDescriptor, unsigned long value);

		/**
		 *   Factory method to create a SEnum variable from a string.
		 */
		static SEnumSp Parse(SEnumTypeDescriptorSp typeDescriptor, string s);
};

#endif  //_SENUM_H
